<template>
  <el-dialog
    v-model="dialogVisible"
    :title="isEdit ? '编辑题目' : '新增题目'"
    width="80%"
    :before-close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-width="120px"
      class="problem-form"
    >
      <el-form-item label="标题" prop="title">
        <el-input v-model="form.title" placeholder="请输入题目标题" />
      </el-form-item>

      <el-form-item label="难度" prop="difficulty">
        <el-select v-model="form.difficulty" placeholder="请选择难度">
          <el-option label="简单" value="Easy" />
          <el-option label="中等" value="Medium" />
          <el-option label="困难" value="Hard" />
        </el-select>
      </el-form-item>

      <el-form-item label="题目类型" prop="type">
        <el-select v-model="form.type" placeholder="请选择题目类型">
          <el-option
            v-for="item in typeOptions"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="标签" prop="tag">
        <el-select v-model="form.tag" placeholder="请选择标签">
          <el-option
            v-for="item in tagOptions"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </el-form-item>

      <el-form-item label="题目描述" prop="problem_description">
        <md-editor
          v-model="form.problem_description"
          :toolbars="markdownToolbars"
          @onUploadImg="onUploadImg"
          height="300px"
        />
      </el-form-item>

      <el-form-item label="输入描述" prop="input_description">
        <md-editor
          v-model="form.input_description"
          :toolbars="markdownToolbars"
          @onUploadImg="onUploadImg"
          height="200px"
        />
      </el-form-item>

      <el-form-item label="输出描述" prop="output_description">
        <md-editor
          v-model="form.output_description"
          :toolbars="markdownToolbars"
          @onUploadImg="onUploadImg"
          height="200px"
        />
      </el-form-item>

      <el-form-item label="标准答案" prop="answer">
        <md-editor
          v-model="form.answer"
          :toolbars="markdownToolbars"
          @onUploadImg="onUploadImg"
          height="300px"
        />
      </el-form-item>

      <el-form-item label="时间限制(ms)" prop="time_limit">
        <el-input-number
          v-model="form.time_limit"
          :min="100"
          :max="10000"
          :step="100"
        />
      </el-form-item>

      <el-form-item label="内存限制(MB)" prop="memory_limit">
        <el-input-number
          v-model="form.memory_limit"
          :min="16"
          :max="512"
          :step="16"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitting">
          {{ isEdit ? '保存' : '创建' }}
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { MdEditor } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import problemApi from '@/api/problem'

interface Props {
  visible: boolean
  problem?: any
}

const props = withDefaults(defineProps<Props>(), {
  visible: false,
  problem: undefined
})

const emit = defineEmits(['update:visible', 'success'])

const dialogVisible = ref(props.visible)
const submitting = ref(false)
const formRef = ref()
const typeOptions = ref([])
const tagOptions = ref([])

const markdownToolbars = {
  bold: true,
  italic: true,
  strikeThrough: true,
  title: true,
  sub: true,
  sup: true,
  quote: true,
  unorderedList: true,
  orderedList: true,
  task: true,
  codeRow: true,
  code: true,
  link: true,
  image: true,
  table: true,
  mermaid: true,
  katex: true,
  revoke: true,
  next: true,
  save: true,
  preview: true,
  htmlPreview: true,
  catalog: true,
  github: true
}

const form = reactive({
  title: '',
  difficulty: 'Easy',
  type: '',
  tag: '',
  problem_description: '',
  input_description: '',
  output_description: '',
  answer: '',
  time_limit: 1000,
  memory_limit: 128
})

const rules = {
  title: [{ required: true, message: '请输入题目标题', trigger: 'blur' }],
  difficulty: [{ required: true, message: '请选择难度', trigger: 'change' }],
  type: [{ required: true, message: '请选择题目类型', trigger: 'change' }],
  tag: [{ required: true, message: '请选择标签', trigger: 'change' }],
  problem_description: [{ required: true, message: '请输入题目描述', trigger: 'blur' }],
  input_description: [{ required: true, message: '请输入输入描述', trigger: 'blur' }],
  output_description: [{ required: true, message: '请输入输出描述', trigger: 'blur' }],
  answer: [{ required: true, message: '请输入标准答案', trigger: 'blur' }]
}

watch(() => props.visible, (val) => {
  dialogVisible.value = val
})

watch(() => dialogVisible.value, (val) => {
  emit('update:visible', val)
})

watch(() => props.problem, (val) => {
  if (val) {
    Object.assign(form, val)
  }
})

const isEdit = computed(() => !!props.problem)

const fetchOptions = async () => {
  try {
    const [typeRes, tagRes] = await Promise.all([
      problemApi.getTypes(),
      problemApi.getTags()
    ])
    typeOptions.value = typeRes.data
    tagOptions.value = tagRes.data
  } catch (error) {
    console.error('获取选项失败:', error)
    ElMessage.error('获取选项失败')
  }
}

const onUploadImg = async (files: File[], callback: (urls: string[]) => void) => {
  const res = await Promise.all(
    files.map((file) => {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => resolve(reader.result)
        reader.onerror = reject
      })
    })
  )
  callback(res as string[])
}

const handleSubmit = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()
    submitting.value = true

    const apiMethod = isEdit.value
      ? () => problemApi.updateProblem(props.problem.id, form)
      : () => problemApi.createProblem(form)

    const res = await apiMethod()
    
    if (res.code === 200 || res.code === 201) {
      ElMessage.success(isEdit.value ? '保存成功' : '创建成功')
      emit('success')
      handleClose()
    }
  } catch (error) {
    console.error(isEdit.value ? '保存失败:' : '创建失败:', error)
    ElMessage.error(isEdit.value ? '保存失败' : '创建失败')
  } finally {
    submitting.value = false
  }
}

const handleClose = () => {
  dialogVisible.value = false
  formRef.value?.resetFields()
}

onMounted(() => {
  fetchOptions()
})
</script>

<style scoped>
.problem-form {
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 20px;
}

.problem-form :deep(.el-form-item__content) {
  flex-direction: column;
  align-items: stretch;
}

.problem-form :deep(.md-editor) {
  width: 100%;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding-top: 20px;
}
</style>
